﻿using System;
using System.Windows.Forms;
using System.Diagnostics;

namespace Analysis_Sorting_Algorithms
{
    public partial class mainForm : Form
    {
        int[] inputarray;
        int[] randoArray;
        int size = 0;
        int NUMBEROFRUNS = 10; //number of times sort is ran
        double totalMS = 0; // the total milliseconds of all the runs
        Stopwatch watch;    //used for timing the running time of sorts
        int avgCompare = 0; //average number of comparisons in algorithm
        public mainForm()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++) //added so the table is loaded with 10 rows when forum loads
            {
                dgv_results.Rows.Add();
                dgv_results.Rows[i].HeaderCell.Value = (i + 1).ToString();
            }
            cbxOrder.Items.Add("Ascending");
            cbxOrder.Items.Add("Descending");
            cbxOrder.Items.Add("Random");
            cbxOrder.SelectedIndex = 0;
            progressBar.Maximum = NUMBEROFRUNS;
        }

        private void combo_ArraySize_SelectedIndexChanged(object sender, EventArgs e)
        {

            if (combo_ArraySize.Text == "100")
                size = 100;
            else if (combo_ArraySize.Text == "1k")
                size = 1000;
            else if (combo_ArraySize.Text == "10k")
                size = 10000;
            else if (combo_ArraySize.Text == "30k")
                size = 30000;

            inputarray = new int[size];

            if (cbxOrder.SelectedIndex == 0)
            {
                for (int i = 0; i < size; i++)
                {
                    inputarray[i] = i + 1;
                }
            }
            else if (cbxOrder.SelectedIndex == 1)
            {
                int elementValue = 1;
                for (int i = size - 1; i >= 0; i--)
                {
                    inputarray[i] = elementValue;
                    elementValue++;
                }
            }
            else
            {
                Random rand = new Random();

                for (int i = 0; i < size; i++)
                {
                    inputarray[i] = rand.Next(1, size); //Creates random array valid numbers are between 1 and Array size (if you have 1-100 and do a sort on 30k numbers your 10x10 will more then likely be all 1's)
                }
            }
           printresult(inputarray);//when size of array changes print new array
            randoArray = new int[inputarray.Length];
            inputarray.CopyTo(randoArray, 0);
            //combo_Sort.Text = "Sort Selction";
            //rtb_result.Text = "Please Select the type of sort you would like to use";
        }

        private void printresult(int[] inputarray)
        {
            if (watch != null && watch.IsRunning)
            {
                watch.Stop();
                totalMS += watch.Elapsed.TotalMilliseconds;
            }
            dgv_results.Rows.Clear(); // Clears so it doesn't add 10 more rows everytime you print
            int max = size;
            int index = 0;
            if (max > 100)
                max = 100;
            for (int i = 0; i < max; i+= 10)
            {
                if (i % 10 == 0)
                {
                    dgv_results.Rows.Add(inputarray[i], inputarray[i + 1], inputarray[i + 2], inputarray[i + 3], inputarray[i + 4], inputarray[i + 5], inputarray[i + 6], inputarray[i + 7], inputarray[i + 8], inputarray[i + 9]);
                    dgv_results.Rows[index].HeaderCell.Value = (index + 1).ToString();
                    index++;
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            printresult(randoArray);
        }

        private void cbxOrder_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (combo_ArraySize.Text != "Size")
            {
                this.combo_ArraySize_SelectedIndexChanged(this, new EventArgs());
            }
        }

        private void Sort_Click(object sender, EventArgs e)
        {
            watch = new Stopwatch();

            rtb_result.Text = "";

            progressBar.Increment(progressBar.Value * -1);
            if (randoArray != null)
            {
                randoArray.CopyTo(inputarray, 0);

                progressBar.Increment(0);
                avgCompare = 0;
                totalMS = 0;
                if (combo_Sort.Text == "Merge Sort")
                {

                    MergeSort sort = new MergeSort();
                    for (int i = 0; i < NUMBEROFRUNS; i++)
                    {
                        randoArray.CopyTo(inputarray, 0);
                        watch.Reset();
                        watch.Start();
                        printresult(sort.RecursiveMerge(inputarray, 0, inputarray.Length - 1, ref avgCompare));
                        progressBar.Increment(1);
                    }

                }
                else if (combo_Sort.Text == "Quick Sort")
                {
                    QuickSort sort = new QuickSort();
                    for (int i = 0; i < NUMBEROFRUNS; i++)
                    {
                        randoArray.CopyTo(inputarray, 0);
                        watch.Reset();
                        watch.Start();
                        printresult(sort.sortIt(inputarray, 0, inputarray.Length - 1, ref avgCompare));
                        progressBar.Increment(1);
                    }
                }
                else if (combo_Sort.Text == "Heap Sort")
                {
                    HeapSort sort = new HeapSort();
                    for (int i = 0; i < NUMBEROFRUNS; i++)
                    {
                        randoArray.CopyTo(inputarray, 0);
                        watch.Reset();
                        watch.Start();
                        printresult(sort.sortIt(inputarray, ref avgCompare));
                        progressBar.Increment(1);
                    }

                }
                else if (combo_Sort.Text == "Bubble Sort")
                {
                    BubbleSort sort = new BubbleSort();
                    for (int i = 0; i < NUMBEROFRUNS; i++)
                    {
                        randoArray.CopyTo(inputarray, 0);
                        watch.Reset();
                        watch.Start();
                        printresult(sort.sortIt(inputarray, ref avgCompare));
                        progressBar.Increment(1);
                    }
                }
                else if (combo_Sort.Text == "Insertion Sort")
                {
                    InsertionSort sort = new InsertionSort();
                    for (int i = 0; i < NUMBEROFRUNS; i++)
                    {
                        randoArray.CopyTo(inputarray, 0);
                        watch.Reset();
                        watch.Start();
                        printresult(sort.sortIt(inputarray, ref avgCompare));
                        progressBar.Increment(1);
                    }
                }
                totalMS = totalMS / NUMBEROFRUNS;
                double finalCompareAvg = 0;
                finalCompareAvg = avgCompare / NUMBEROFRUNS;

                tbxNumComp.Text = Convert.ToString(finalCompareAvg);
                rtb_result.Text = "Average time elapsed for " + NUMBEROFRUNS + " sorts\n"
                                   + totalMS / 1000 + " sec\n" + totalMS + "  ms\n" + totalMS * 1000000 + " ns\n";
            }
        }

        private void tbxNumRun_Leave(object sender, EventArgs e)
        {
            
            int temp = 0;
            if (int.TryParse(tbxNumRun.Text.Trim(), out temp))
            {
                if (temp > 0)
                {
                    NUMBEROFRUNS = temp;
                    progressBar.Increment(progressBar.Value * -1);
                    progressBar.Maximum = NUMBEROFRUNS;
                }
                else
                {
                    tbxNumRun.Text = NUMBEROFRUNS.ToString();
                }
            }
            else 
            {
                tbxNumRun.Text = NUMBEROFRUNS.ToString();
            }
        }

    }
}
